// 线程的封装
#include <iostream>
#include <string>
#include <cstring>
#include <ctime>
#include <unistd.h>
#include <pthread.h>
#include <stdio.h>

class Thread
{
public:
    typedef enum
    {
        New = 0,
        Running,
        Exit
    } Sta;

    typedef void (*func_t)(void *);

public:
    Thread(int n, func_t func, void *args) : _tid(0), _status(New), _func(func), _args(args)
    {
        char name[128];
        snprintf(name, sizeof(name), "thread-%d", n);
        _name = name;
    }
    // Thread(int n,func_t func,void *args):_tid(0),_n(n),_func(func),_args(args),_status(New)
    // {
    //     char name[128];
    //     snprintf(name,sizeof (name),"thread[%d]",_n);
    //     _name=name;

    // }
    int status() // 获取线程状态
    {
        return _status;
    }
    string threadname() // 获取线程名字
    {
        return _name;
    }

    pthread_t threadid() // 获取线程id
    {
        if (_status == Running)
        {
            return _tid;
        }
        else
        {
            return -1;
        }
    }
    // 类的成员函数，具有默认参数this,需要static
    // 但是会有新的问题：static成员函数，无法直接访问类属性和其他成员函数

    // 如果是按照成员函数传参的话就是void*runcall(Thread *this void*args)，现在只有一个传参无法进行
    static void *runcall(void *args)
    {
        Thread *ts = (Thread *)args; // 拿下对象

        (*ts)();
        return nullptr;
    }

    void operator()() // 仿函数
    {
        if (_func != nullptr)
            _func(_args);
    }

    void Runing() // 创建线程
    {
        int n = pthread_create(&_tid, nullptr, runcall, this); // 传入this，就能访问原有的成员了
        if (n != 0)
            exit(-2);

        _status = Running;
    }

    void join()
    {
        int n = pthread_join(_tid, nullptr);
        if (n != 0)
        {
            cerr << "pthread join false" << endl;
            return;
        }

        _status = Exit;
    }

    ~Thread()
    {
    }

private:
    pthread_t _tid;
    string _name;
    func_t _func; // 线程要执行的回调函数
    void *_args;
    Sta _status; // 状态
};